const { app } = require('electron');
const path = require('path');
const fs = require('fs');
const { spawn, execSync } = require('child_process');

let pythonServiceProcesses = [];

function ensurePortFree(port, label) {
  try {
    if (process.platform === 'win32') {
      // Windows 简化处理：不在此实现，避免误杀。可按需扩展。
      return;
    }
    // macOS/Linux 使用 lsof 找到占用端口的 PID 并终止
    const pidsRaw = execSync(`lsof -ti tcp:${port} || true`, { encoding: 'utf8' }).trim();
    if (!pidsRaw) return;
    const pids = pidsRaw.split(/\s+/).filter(Boolean);
    for (const pid of pids) {
      try {
        process.kill(Number(pid), 'SIGTERM');
      } catch {}
    }
    // 等待片刻后强杀仍存活的
    setTimeout(() => {
      for (const pid of pids) {
        try {
          process.kill(Number(pid), 0); // 检查是否仍存在
          try { process.kill(Number(pid), 'SIGKILL'); } catch {}
        } catch {}
      }
    }, 300);
    console.log(`[py:${label}] freed port ${port}`);
  } catch (e) {
    console.warn(`[py:${label}] ensurePortFree(${port}) failed:`, e.message || e);
  }
}

function resolvePyExecutable(relativePathWithinPy) {
  const isPackaged = app.isPackaged;
  if (!isPackaged) {
    let devPath = path.join(__dirname, 'resources', 'py', relativePathWithinPy);
    if (process.platform === 'win32' && !devPath.endsWith('.exe')) devPath += '.exe';
    return devPath;
  }

  const candidates = [
    path.join(process.resourcesPath, 'py', relativePathWithinPy),
    path.join(process.resourcesPath, 'resources', 'py', relativePathWithinPy),
  ];

  let executablePath = candidates.find(p => fs.existsSync(p)) || candidates[0];
  if (process.platform === 'win32' && !executablePath.endsWith('.exe')) {
    executablePath = executablePath + '.exe';
  }
  return executablePath;
}

function spawnPythonService(label, relativePathWithinPy) {
  const exePath = resolvePyExecutable(relativePathWithinPy);
  const cwd = path.dirname(exePath);
  try {
    if (process.platform !== 'win32') {
      fs.chmodSync(exePath, 0o755);
    }
  } catch (e) {
    console.warn(`chmod failed for ${exePath}:`, e);
  }
  const child = spawn(exePath, [], {
    cwd,
    env: {
      ...process.env,
      FLASK_ENV: 'production',
      FLASK_DEBUG: '0',
      // 不设置 WERKZEUG_RUN_MAIN，避免 werkzeug 期望的内部变量缺失导致 KeyError
    },
    stdio: 'pipe',
  });

  child.stdout && child.stdout.on('data', (data) => {
    console.log(`[py:${label}] ${data}`.toString());
  });
  child.stderr && child.stderr.on('data', (data) => {
    console.error(`[py:${label}:err] ${data}`.toString());
  });
  child.on('exit', (code, signal) => {
    console.log(`[py:${label}] exited with code ${code} signal ${signal}`);
  });

  pythonServiceProcesses.push(child);
  return child;
}

function startPythonServices() {
  // 先确保端口不被占用（当前已知 case 使用 6764）
  ensurePortFree(6764, 'case');
  spawnPythonService('analysis', path.join('analysis', 'api', 'api'));
  spawnPythonService('case', path.join('case', 'api', 'api'));
  spawnPythonService('dp', path.join('dp', 'api', 'api'));
}

function stopPythonServices() {
  for (const child of pythonServiceProcesses) {
    try {
      if (child && !child.killed) {
        child.kill('SIGTERM');
      }
    } catch (e) {
      console.warn('Failed to SIGTERM child, trying SIGKILL', e);
      try { child.kill('SIGKILL'); } catch {}
    }
  }
  pythonServiceProcesses = [];
}

module.exports = { startPythonServices, stopPythonServices }; 